#!/bin/bash

# Special File:
#
# branch_flag
# branch-config
# 	|- filelist
#	|- ignorelist
# 	|- includelist
# 	|- symlist
#	|- destpath
#	|- autodelete

function i() {
	mkdir branch-config
	touch branch-config/filelist
	touch branch-config/ignorelist
	touch branch-config/includelist
	touch branch-config/symlist
	echo "$1" >branch-config/destpath
	mkdir -p "$1"
	echo "$2" >branch-config/autodelete
}

function r() {
	branch_name=$(<branch_flag)
	destpath=$(<branch-config/destpath)
	mkdir -p "$destpath"/"$branch_name"
	autodelete=$(<branch-config/autodelete)

	if [[ $1 == s ]]; then
		rsync -ruvtph --delete --progress\
			--include-from=branch-config/includelist\
			--exclude-from=branch-config/ignorelist\
			--files-from=branch-config/filelist\
			--safe-links\
			./ "$destpath"/"$branch_name"/
		if [[ $(<branch-config/symlist) != "" ]]; then
			mapfile -t symfiles < <(sed -e 's#^#'"$PWD"/'#g' branch-config/symlist)
			ln -sf "${symfiles[@]}" "$destpath"/"$branch_name"/
		fi
	fi

	echo Branch Info: run at "$branch_name"@"$destpath":"$autodelete"
	! cd "$destpath"/"$branch_name" && echo "changing to $destpath/$branch_name error!" && return 1
	shift 1
	echo Command: "$@"
	"$@"
	returncode=$?
	! cd ~- && echo "changing back to workdir error!" && return 1
	echo Branch Info: run at "$branch_name"@"$destpath":"$autodelete"

	if [[ $autodelete -ne 0 ]]; then
		rm -rf "${destpath:?Empty Destpath}"/"$branch_name"
	fi

	return $returncode
}

function h() {
	cat <<"eof"
子命令：
  * init path {1|0} - 初始化项目，第一个参数指定创建快照路径，第二个参数可选，默认
    为0，表示每次执行完后是否自动删除快照
  * run command - 在当前分支的快照下执行命令，执行命令前更新快照
  * rep command - 在当前分支的快照下执行命令，执行命令前不更新快照
  * help - 打印本帮助
特殊文件：
  * branch_flag - 记录当前分支
  branch-config目录下
  * filelist - 用于rsync的--files-from选项
  * ignorelist - 用于rsync的--exlcude-from选项
  * includelist - 用于rsync的--include-from选项
  * symlist - 指定需使用ln建立软链接的文件
  * destpath - 记录创建快照的路径
  * autodelete - 记录每次执行完后是否自动删除快照
eof
}

case $1 in
	init)
		i "${2:?Empty destination!}" "${3:-0}";;
	run)
		shift 1
		r s "$@";;
	rep)
		shift 1
		r d "$@";;
	help)
		h;;
esac
